package ru.stepanovdn.trading.server.service.notification

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.LoggerContext
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.classic.spi.LoggingEvent
import com.pengrad.telegrambot.TelegramBot
import com.pengrad.telegrambot.UpdatesListener
import com.pengrad.telegrambot.request.SendMessage
import io.micrometer.common.util.StringUtils
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.util.function.Consumer
import jakarta.annotation.PostConstruct
import ch.qos.logback.core.UnsynchronizedAppenderBase

/**
 * Service to send messages and errors in preconfigured channels
 *
 *
 * Telegram channel configuration
 * - telegram.bot.token
 * - telegram.bot.chat-id
 */
@Service
class NotificationService {

    private val log = LoggerFactory.getLogger(javaClass)

    @Value("\${telegram.bot.token:}")
    private val telegramBotToken: String? = null

    @Value("\${telegram.bot.chat-id:}")
    private val telegramBotChatId: String? = null

    private var bot: TelegramBot? = null

    fun sendMessage(content: String?) {
        if (bot != null && StringUtils.isNotEmpty(telegramBotChatId)) {
            val message: SendMessage = SendMessage(telegramBotChatId, content)
            bot!!.execute(message)
        }
    }

    @PostConstruct
    private fun init() {
        // отправляем сообщение в telegram в случае level ERROR в логах
        val loggerContext = LoggerFactory.getILoggerFactory() as LoggerContext
        val appender: UnsynchronizedAppenderBase<ILoggingEvent?> = object : UnsynchronizedAppenderBase<ILoggingEvent?>() {
            override fun append(eventObject: ILoggingEvent?) {
                if (eventObject is LoggingEvent) {
                    if (eventObject.level == Level.ERROR) {
                        sendMessage(eventObject.toString())
                    }
                }
            }
        }
        loggerContext.loggerList.forEach(Consumer { l: Logger -> l.addAppender(appender) })
        appender.start()

        // по умолчанию на любое сообщение ответим в телеграм чат отправив chatId
        if (StringUtils.isNotEmpty(telegramBotToken)) {
            this.bot = TelegramBot(telegramBotToken)
            bot!!.setUpdatesListener { updates ->
                updates.forEach { update ->
                    val chatId: Long? = update.message().chat().id()
                    val messageIn: String? = update.message().text()
                    if (messageIn != null) {
                        val messageOut = String.format("Received from chat id %s: %s", chatId, messageIn)
                        bot!!.execute(SendMessage(update.message().chat().id(), messageOut))
                    }
                }
                UpdatesListener.CONFIRMED_UPDATES_ALL
            }
        }

        if (StringUtils.isEmpty(telegramBotToken) || StringUtils.isEmpty(telegramBotChatId)) {
            log.info(
                "Telegram properties no defined properly: telegram.bot.token {}, telegram.bot.chat-id {}",
                telegramBotToken, telegramBotChatId
            )
        }
    }
}
